package interfaces;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

import dinnerSimulation.Environment;
import dinnerSimulation.Floor;
import dinnerSimulation.Square;
import dinnerSimulation.Square.Type;

/**
 * Implement a JPanel to represent the environment and the agent
 * 
 */
public class GridPanel extends JPanel {

	private static final long serialVersionUID = 1L;
	private static JLabel[][] labelMatrix;
	public static ImageIcon dirtIcon, obstacleIcon, tileIcon, vacuumIcon,
			flowerIcon, suitIcon, catIcon, groceriesIcon, foodIcon, tableIcon, doorIcon,
			gardenIcon, frontDoorIcon, tile1Icon, tile2Icon, tile3Icon,
			tile4Icon, tile5Icon, ciccio1Icon, ciccio2Icon, ciccio3Icon, ciccio4Icon,
			ciccioFlIcon, dinnertableIcon, renataIcon, endIcon;
	public int labelSize;
	static Environment env;

	static Square.Type currType;
	static ImageIcon currIcon;
	
	/*Variables to control the object selected*/
	
	boolean bSuit= false;
	boolean bTable = false;
	boolean bDinner = false;
	boolean bRoses = false;
	boolean bBedroomDoor = false;
	boolean bKitchenDoor = false;
	boolean bHallDoor = false;
	boolean bLivingDoor = false;
	boolean bCiccio=false;
	/**
	 * Generate a graphic representation of the environment and its elements
	 * 
	 * @param env
	 *            an environment configuration
	 */
	public GridPanel(Environment env) {
		GridPanel.env = env;
		init();
		update();

	}

	/**
	 * Generate a GridLayout according with the width and length of the floor
	 * and set the images that correspond to each element of the environment
	 */
	void init() {

		setLayout(new FlowLayout());

		JPanel flowPanel = new JPanel();
		add(flowPanel);
		flowPanel.setLayout(new GridLayout(env.floor.length, env.floor.width));

		dirtIcon = ImageLoader.dirtIcon;
		obstacleIcon = ImageLoader.obstacleIcon;
		ciccio1Icon = ImageLoader.ciccio1Icon;
		ciccio2Icon = ImageLoader.ciccio2Icon;
		ciccio3Icon = ImageLoader.ciccio3Icon;
		ciccio4Icon = ImageLoader.ciccio4Icon;
		tileIcon = ImageLoader.tileIcon;
		tile1Icon = ImageLoader.tile1Icon;
		tile2Icon = ImageLoader.tile2Icon;
		tile3Icon = ImageLoader.tile3Icon;
		tile4Icon = ImageLoader.tile4Icon;
		tile5Icon = ImageLoader.tile5Icon;
		vacuumIcon = ImageLoader.vacuumIcon;
		suitIcon = ImageLoader.suitIcon;
		flowerIcon = ImageLoader.flowerIcon;
		tableIcon = ImageLoader.tableIcon;
		foodIcon = ImageLoader.foodIcon;
		groceriesIcon = ImageLoader.groceriesIcon;
		doorIcon = ImageLoader.doorIcon;
		frontDoorIcon = ImageLoader.frontDoorIcon;
		gardenIcon = ImageLoader.gardenIcon;
		labelMatrix = new JLabel[env.floor.length][env.floor.width + 1];
		dinnertableIcon = ImageLoader.dinnertableIcon;
		ciccioFlIcon = ImageLoader.ciccioFlIcon;
		renataIcon = ImageLoader.renataIcon;
		endIcon = ImageLoader.endIcon;
		
		
		currType = Type.CLEAN;
		// currIcon = tileIcon;

		for (int i = 0; i < env.floor.length; i++)
			for (int j = 0; j <= env.floor.width; j++) {
				GridBagConstraints constraints = new GridBagConstraints();
				constraints.fill = GridBagConstraints.BOTH;
				constraints.gridx = i;
				constraints.gridy = j;
				final JLabel label = new JLabel();
				label.setBackground(Color.WHITE);
				label.setPreferredSize(new Dimension(ImageLoader.iconSize,
						ImageLoader.iconSize));
				label.addMouseListener(new ClickHandler(label, i, j));
				labelMatrix[i][j] = label;
				flowPanel.add(label, constraints);
			}
	}

	/**
	 * Generate a graphic representation of the environment on a thread,
	 * according with the state of each tile (square) and the position of the
	 * agent
	 */
	public void update() {

		for (int i = 0; i < env.floor.length; i++)
			for (int j = 0; j <= env.floor.width; j++) {
				/* Sets the type of room in the position width+1 */
				if (j == env.floor.width
						&& (env.floor.get(i, j) == Square.Type.STATE)) {
					if (env.floor.room[i] == Floor.roomType.BEDROOM)
						labelMatrix[i][j].setIcon(tile1Icon);
					else if (env.floor.room[i] == Floor.roomType.LIVINGROOM)
						labelMatrix[i][j].setIcon(tile2Icon);
					else if (env.floor.room[i] == Floor.roomType.KITCHEN)
						labelMatrix[i][j].setIcon(tile3Icon);
					else if (env.floor.room[i] == Floor.roomType.HALL)
						labelMatrix[i][j].setIcon(tile4Icon);
					else if (env.floor.room[i] == Floor.roomType.ENTRANCE && env.floor.get(i, j).equals(Square.Type.END))
						labelMatrix[i][j].setIcon(endIcon);
					else
						labelMatrix[i][j].setIcon(tile5Icon);
				}

				
				boolean entrance = env.floor.get(i-1, j) == Square.Type.DOOR &&
						env.floor.room[i] == Floor.roomType.ENTRANCE;
				
				if(env.agent.died && entrance ){
					System.out.println("renata icon");
					env.floor.set(i, j, Square.Type.RENATA);
					labelMatrix[i][j].setIcon(renataIcon);
				}

				
		       if (env.floor.get(i, j) == Square.Type.CLEAN) {
		    	 
					labelMatrix[i][j].setIcon(tileIcon);
				}
				if (env.agent.x == i && env.agent.y == j) {
				
					labelMatrix[i][j].setIcon(ciccio1Icon);
				}
				else{ 
				
				if (env.floor.get(i, j) == Square.Type.GARDEN)
					labelMatrix[i][j].setIcon(gardenIcon);
				
				if (env.floor.room[i] == Floor.roomType.BEDROOM
						&& env.floor.get(i, j) == Square.Type.SMOKING)
					labelMatrix[i][j].setIcon(suitIcon);
				
				if (env.floor.get(i, j) == Square.Type.FLOWERS)
					labelMatrix[i][j].setIcon(flowerIcon);
				if (env.floor.get(i, j) == Square.Type.MEAL && !env.agent.isMEAL_READY())
					labelMatrix[i][j].setIcon(groceriesIcon);
				if (env.floor.get(i, j) == Square.Type.MEAL && env.agent.isMEAL_READY())
					labelMatrix[i][j].setIcon(foodIcon);
				if (env.floor.get(i, j) == Square.Type.DOOR
						&& env.floor.room[i] != Floor.roomType.ENTRANCE)
					labelMatrix[i][j].setIcon(doorIcon);
				if (env.floor.get(i, j) == Square.Type.DOOR
						&& env.floor.room[i] == Floor.roomType.ENTRANCE)
					labelMatrix[i][j].setIcon(frontDoorIcon);

				}
			
					if((env.agent.x == i && env.agent.y == j)
							&& env.agent.isSUIT_UP() && !env.agent.isTAKE_MEAL())
						labelMatrix[i][j].setIcon(ciccio2Icon);
					
					if ((env.agent.x == i && env.agent.y == j)
							&& env.agent.isTAKE_MEAL() && !env.agent.isFLOWERS_TAKEN())
							labelMatrix[i][j].setIcon(ciccio3Icon);
					
					if ((env.agent.x == i && env.agent.y == j)
							&& env.agent.isFLOWERS_TAKEN())
						labelMatrix[i][j].setIcon(ciccioFlIcon);
					
					if(env.agent.x==i && env.agent.y==j && env.agent.isTABLE_READY() &&
							!env.agent.isFLOWERS_TAKEN()){
						labelMatrix[i][j].setIcon(ciccio2Icon);
					}
					
					if(env.agent.x==i && env.agent.y==j && env.agent.isENTRANCE()){
						labelMatrix[i][j].setIcon(ciccio4Icon);
						labelMatrix[i][j].setIcon(endIcon);
					}
					
					if(env.agent.energy==1 && env.floor.get(i, j) == Square.Type.ENTRANCE){
						System.out.println("renata icon");
						labelMatrix[i][j].setIcon(renataIcon);
					}
					
				
				
				
				if (env.floor.get(i, j) == Square.Type.TABLE){
					if(env.agent.isTABLE_READY()){
						System.out.println("dinnerTableIcon");
						labelMatrix[i][j].setIcon(dinnertableIcon);
						
					}
						
					else
						labelMatrix[i][j].setIcon(tableIcon);
				}
				
			}
		
		
		try {
			Thread.sleep(250);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	* Cleans the cell on position x,y
	* @param i coordinate X
	* @param j coordinate Y
	*/
	public static void clean(int i, int j){
	labelMatrix[i][j].setIcon(tileIcon);
	env.floor.set(i, j, Square.Type.CLEAN);
	}

	public void initialPos() {

		/*String obj = "\n";
		String res = "\n";
		String doors = "\n";
		String room = "\n";
		String adj = "\n";
		String position = "\n";

		int pos;

		obj += "object(ciccio). object(meal). object(flowers). object(table). "
				+ "object(smoking).";

		for (int k = 0; k <= env.floor.width; k++)
			position += "\nposition(" +(k+1)+ ").";

		for (int i = 0; i < env.floor.length; i++) {
			int rpos = i + 1;
			room = room + "room(" + (i + 1) + ","
					+ env.floor.room[i].toString().toLowerCase() + " ).\n";

			for (int j = 0; j <= env.floor.width; j++) {
				pos = j + 1;
				if (env.floor.get(i, j) == Square.Type.CAT)
					res = res + "at("
							+ Square.Type.CAT.toString().toLowerCase() + ","
							+ env.floor.room[i].toString().toLowerCase() + ","
							+ pos + ").\n";

				if (env.floor.room[i] == Floor.roomType.BEDROOM
						&& env.floor.get(i, j) == Square.Type.SMOKING) {
					res = res + "at("
							+ Square.Type.SMOKING.toString().toLowerCase()
							+ "," + env.floor.room[i].toString().toLowerCase()
							+ "," + pos + ").\n";
				}

				if (env.floor.get(i, j) == Square.Type.FLOWERS) {
					res = res + "at("
							+ Square.Type.FLOWERS.toString().toLowerCase()
							+ "," + env.floor.room[i].toString().toLowerCase()
							+ "," + pos + ").\n";
				}

				if (env.floor.get(i, j) == Square.Type.CICCIO) {
					res = res + "at("
							+ Square.Type.CICCIO.toString().toLowerCase() + ","
							+ env.floor.room[i].toString().toLowerCase() + ","
							+ pos + ").\n";

				}
				if (env.floor.get(i, j) == Square.Type.TABLE) {
					res = res + "at("
							+ Square.Type.TABLE.toString().toLowerCase() + ","
							+ env.floor.room[i].toString().toLowerCase() + ","
							+ pos + ").\n";
				}

				if (env.floor.get(i, j) == Square.Type.MEAL)
					res = res + "at("
							+ Square.Type.MEAL.toString().toLowerCase() + ","
							+ env.floor.room[i].toString().toLowerCase() + ","
							+ pos + ").\n";

				if (env.floor.get(i, j) == Square.Type.DOOR
						&& env.floor.room[i] != Floor.roomType.ENTRANCE) {
					doors = doors + "\ndoor_at("
							+ env.floor.room[i].toString().toLowerCase() + ","
							+ env.floor.room[i + 1].toString().toLowerCase()
							+ "," + pos + ").\n" + "door_at("
							+ env.floor.room[i + 1].toString().toLowerCase()
							+ "," + env.floor.room[i].toString().toLowerCase()
							+ "," + pos + ").\n";
					adj += "\nadjacent(" + rpos + "," + pos + "," + (rpos + 1)
							+ "," + pos + ").";
					adj += "\nadjacent(" + (rpos + 1) + "," + pos + "," + rpos
							+ "," + pos + ").";
				}
				if (pos < env.floor.width) {
					adj += "\nadjacent(" + rpos + "," + pos + "," + rpos + ","
							+ (pos + 1) + ").";
					adj += "\nadjacent(" + rpos + "," + (pos + 1) + "," + rpos
							+ "," + pos + ").";
				}

			}
		}
		System.out.println(obj + room + position + res + doors + adj);

		try {
			// Create file

			FileWriter fstream = new FileWriter("dlv/ciccio_pasticcio_back.dl");
			BufferedWriter out = new BufferedWriter(fstream);
			out.write("%ciccio_pasticcio_back.dl");
			out.write(obj + room + position + doors + adj);

			out.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
		
		try {
			// Create file

			FileWriter fstream = new FileWriter("dlv/ciccio_pasticcio_initial.plan");
			BufferedWriter out = new BufferedWriter(fstream);
			out.write("%ciccio_pasticcio_initial.plan");
			out.write(res);

			out.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
*/
	}

	/**
	 * Generates a string with a message with the objects not selected*/
	String errorMessage(){
		
		String messg ="";
		
		
		if(!bSuit)
			messg += "Suit is not selected\n";
		if(!bTable)
			messg += "Table is not selected\n";
		if( !bDinner )
			messg += "Dinner is not selected\n";
		if(!bRoses)
			messg += "Roses is not selected\n";
		if(!bBedroomDoor)
			messg += "Bedroom Door  is not selected\n";
	
		if(!bKitchenDoor)
			messg += "Kitchen Door is not selected\n";
		if(!bHallDoor)
			messg += "Hall Door is not selected\n";
		if(!bLivingDoor)
			messg += "Living Room Door  is not selected\n";

	
		if(!bCiccio)
			messg += "Ciccio initial position is not selected\n";
			
		return messg;
		
	}
	/**
	 * To controll that all elements has been selected
	 * */
	boolean isAllSelected(){
		
		if( bSuit && bTable && bDinner && bRoses &&  bBedroomDoor && bKitchenDoor &&
				bHallDoor && bLivingDoor  && bCiccio)
			return true;
		else return false;
	}

	/**
	 * To controll that all elements has been selected
	 * */
	boolean resetAllSelected(){
		
		if( bSuit = bTable= bDinner =bRoses &&  bBedroomDoor && bKitchenDoor &&
				bHallDoor && bLivingDoor  && bCiccio)
			return true;
		else return false;
	}
	/**
	 * Controls in each position of the grid the elements assigned
	 * */
	public boolean isComplete() {
		
		for (int i = 0; i < env.floor.length; i++)
			for (int j = 0; j < env.floor.width; j++) {
				
				if(env.floor.room[i] == Floor.roomType.BEDROOM){
					
					
					if (env.floor.get(i, j) == Square.Type.SMOKING) {
						bSuit=true;
					}
					if (env.floor.get(i, j) == Square.Type.DOOR) {
						bBedroomDoor=true;
					}
						
				}		
				if(env.floor.room[i] == Floor.roomType.KITCHEN){
					
				
					if (env.floor.get(i, j) == Square.Type.MEAL) {
						bDinner=true;
					}
					if (env.floor.get(i, j) == Square.Type.DOOR) {
						bKitchenDoor=true;
					}
						
				}
				if(env.floor.room[i] == Floor.roomType.HALL){
					
					
					if (env.floor.get(i, j) == Square.Type.FLOWERS) {
						bRoses=true;
					}
					if (env.floor.get(i, j) == Square.Type.DOOR) {
						bHallDoor=true;
					}
						
				}
				if(env.floor.room[i] == Floor.roomType.LIVINGROOM){
				
					if (env.floor.get(i, j) == Square.Type.TABLE) {
						bTable=true;
					}
					if (env.floor.get(i, j) == Square.Type.DOOR) {
						bLivingDoor=true;
					}
						
				}
				
				
				if (env.agent.x == i && env.agent.y == j) {
					bCiccio=true;
				}
				
				
			} //end of for
		return isAllSelected();
	}
	
}
